home *** CD-ROM | disk | FTP | other *** search
- /* This small sample shows how to use the PBCatSearch function. */
- /* It presents a dialog where you can enter any Creator and File Type, then it */
- /* searches for one (1) file with that creator and type */
- /* When it finds it, it will show you the file name. */
- /* C.K. Haun */
- /* Apple Developer Tech Support */
- /* Comments or request, ALink C.K.HAUN */
- /* Oct 16, 1991, Tokyo */
-
- #include <Dialogs.h>
- #include <Controls.h>
- #include <QuickDraw.h>
- #include <Windows.h>
- #include <ToolUtils.h>
- #include <OSUtils.h>
- #include <Menus.h>
- #include <Fonts.h>
- #include <resources.h>
- #include <memory.H>
- #include <files.h>
-
- /* constants for this application */
- /* two dialog boxes */
- #define kSearch 128
- #define kFoundIt 129
- /* one alert box */
- #define kAsk 130
-
- #define kOneKilobyte 1024
-
- /* constants for key codes I will be using for the dialog filter */
- enum {
- kEnterKey = 0x03, kBackSpace = 8, kReturnKey = 0x0D, kTabKey, kEscKey = 0x1B, kLeftArrow, kRightArrow, kUpArrow, kDownArrow,
- kDeleteKey = 0x7F
- };
- /* prototypes for this file */
-
- void DoCatSearch(void);
- ControlHandle SnatchHandle(DialogPtr thebox, short theGetItem);
- pascal Boolean letterFilter(DialogPtr dialer, EventRecord *myDialogEvent, short *theDialogItem);
- Boolean IsEditKey(char theKey);
-
- #ifdef powerc
- QDGlobals qd;
- #endif
-
-
- /* the main routine. All this does is initialize managers and call DoCatSearch */
- main()
- {
-
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
- DoCatSearch();
- }
-
- /* DoCatSearch asks the user for the Creator and File type of the file to be found. */
- /* Then, it initializes the parameter blocks for the PBCatSearch call, and makes */
- /* the call. When it finds a file with the correct creator and file type, it */
- /* shows the user */
- void DoCatSearch(void)
- {
- short bufferSize = kOneKilobyte * 16; /* I will be using this to make */
- /* the optimization buffer */
- OSErr myError; /* general error variable */
- DialogPtr search; /* dialog pointer varialbe */
- ModalFilterUPP myModalFilterUPP;
- short alertResult;
-
- /* here I am initializing the cat search parameter block (csBlockPtr) using */
- /* NewPointerClear so I know that all the fields in the parameter block */
- /* will be clear before I start. This helps prevent errors */
- CSParamPtr csBlockPtr = NewPtrClear(sizeof(CSParam));
-
- short hitItem = 0; /* for the dialog routines */
- long dirIDUnused; /* for GetVol use */
- /* these are the default Creator and Type I will be looking for. These can */
- /* be changed by the user when the dialog box is presented to them */
- Str32 Creator = "\pMACS";
- Str32 Type = "\pFNDR";
-
- Str32 nulString = "\p"; /* an empty string to pass to PBCatSearch */
-
- /* Open a Dialog and ask the user for the Creator and Type they wish to */
- /* search for */
- search = GetNewDialog(kAsk, nil, (WindowPtr)-1);
-
- /* create a modal filter UPP- this will be freed when the */
- /* application quits */
-
- myModalFilterUPP = NewModalFilterProc(letterFilter);
- while (hitItem != ok) { /* wait until they hit the 'ok' button */
- ModalDialog(myModalFilterUPP, &hitItem);
- }
- /* now get the creator and file type they entered. */
- GetDialogItemText((Handle)SnatchHandle(search, 4), Creator);
- GetDialogItemText((Handle)SnatchHandle(search, 5), Type);
-
- DisposeDialog(search); /* remove the dialog from the screen */
-
- /* initialize the parameter block */
- /* first I see if we got the memory we need */
- if (csBlockPtr) {
- /* yes, we have the memory to work. Build the parameter block */
-
- /* First get the memory for the two other parameter blocks we need */
- /* these blocks are used to give PBCatSearch to exact information */
- /* it needs to match a file */
- csBlockPtr->ioSearchInfo1 = (CInfoPBPtr)NewPtrClear(sizeof(CInfoPBRec));
- csBlockPtr->ioSearchInfo2 = (CInfoPBPtr)NewPtrClear(sizeof(CInfoPBRec));
- /* check to be sure we got the memory we need */
- if (csBlockPtr->ioSearchInfo1 && csBlockPtr->ioSearchInfo2) {
- /* we have memory */
- /* Now allocate a buffer to hold the result of the PBCatSearch call */
- /* this is an array of ioMatchPtr, which is defined as an FSSpecPtr */
- /* so we will get the size of an FSSpec record */
- /* I am only asking for one file, so I will only ask for that much memory */
- csBlockPtr->ioMatchPtr = (FSSpecPtr)NewPtrClear(sizeof(FSSpec) * 1); /* only looking for 1 */
- if (csBlockPtr->ioMatchPtr) {
- /* got the memory for that */
- /* Now see if we can create an optimization buffer */
- /* I will start by asking for a 16K buffer */
- /* If I cannot get that, I will keep reducing my request */
- /* until I get to zero. A one K buffer is better than no */
- /* buffer at all */
- while(bufferSize){
- csBlockPtr->ioOptBuffer = NewPtr(bufferSize);
- if(csBlockPtr->ioOptBuffer){
- break;
- } else {
- bufferSize -= kOneKilobyte;
- }
- }
- if (csBlockPtr->ioOptBuffer)
- csBlockPtr->ioOptBufSize = bufferSize;
- else
- csBlockPtr->ioOptBufSize = 0; /* no buffer, sorry */
- /* I want to find one file */
- csBlockPtr->ioReqMatchCount = 1;
- /* No timeout. PBCatSearch will keep running until it finds */
- /* a file or searches the whole volume */
- csBlockPtr->ioSearchTime = 0; /* no timeout */
- /* Change this parameter in a real application. In a real application, */
- /* you would want to come back periodically (every 2 seconds or so) */
- /* to do various things like; */
- /* 1) Spin a 'wait' cursor */
- /* 2) Update a thermometer bar */
- /* 3) Call WaitNextEvent, so the user can switch out */
- /* of your application while you are searching */
- /* Watch the Finder's "Find" command work so you can see how this */
- /* is done */
- }
- }
- }
- /* This sample only works on the default directory, so I am getting the */
- /* volume reference number for that volume here */
- HGetVol(nil, &csBlockPtr->ioVRefNum, &dirIDUnused); /* get default volume for search */
- /* make sure these two pointer are clear */
- csBlockPtr->ioSearchInfo1->hFileInfo.ioNamePtr = nil;
- csBlockPtr->ioSearchInfo2->hFileInfo.ioNamePtr = nil;
-
- /* Here I am moving the User's selected creator and file type into the first */
- /* search parameter block. If they entered a bad creator or type, I default to the */
- /* Finder */
- if (Creator[0] == 4)
- BlockMove((Ptr)&Creator + 1, (Ptr)&csBlockPtr->ioSearchInfo1->hFileInfo.ioFlFndrInfo.fdCreator, 4);
- else
- csBlockPtr->ioSearchInfo1->hFileInfo.ioFlFndrInfo.fdCreator = 'MACS';
-
- if (Type[0] == 4)
- BlockMove((Ptr)&Type + 1, (Ptr)&csBlockPtr->ioSearchInfo1->hFileInfo.ioFlFndrInfo.fdType, 4);
- else
- csBlockPtr->ioSearchInfo1->hFileInfo.ioFlFndrInfo.fdType = 'FNDR';
- /* This is the paramter that specifies HOW to search */
- csBlockPtr->ioSearchBits = fsSBFlFndrInfo;
- /* in this case, I am saying to search by Finder information. */
- /* there are MANY values allowed here, and you can also use */
- /* many combinations, as*/
- /* fsSBPartialName search for partial names
- fsSBFullName search for full names
- fsSBFlAttrib "" directory flags
- fsSBFlFndrInfo Finder info
- fsSBFlLgLen data fork logical size
- fsSBFlPyLen dat fork physical size
- fsSBFlRLgLen resource fork logical size
- fsSBFlRPyLen resource fork physical size
- fsSBFlCrDat creation date
- fsSBFlMdDat modification date
- fsSBFlBkDat backup date
- fsSBFlXFndrInfo more finder info
- fsSBFlParID file parent ID (directory ID)
- fsSBDrUsrWds directory information
- fsSBDrNmFls number of files in a folder
- fsSBDrCrDat folder creation date
- fsSBDrMdDat "" mod date
- fsSBDrBkDat "" backup date
- fsSBDrFndrInfo finder folder information
- */
- /* and you can combine many of these, to create unique searches */
-
- /* Set up the second search parameter block */
- /* For the search I am doing (creator/filetype) these need to be set to -1 */
- csBlockPtr->ioSearchInfo2->hFileInfo.ioFlFndrInfo.fdCreator = 0xFFFFFFFF;
- csBlockPtr->ioSearchInfo2->hFileInfo.ioFlFndrInfo.fdType = 0xFFFFFFFF;
- /* For other searches (like by modification date) this would indicate the end of the */
- /* search range. This allows you to, for example, search for all the files */
- /* modified between October 1 1991 and October 12 1991 */
- /* Many more combinations are possible, see Inside Mac VI */
-
- /* Setting up my 'wait' dialog */
- ParamText(Creator, Type, "\p", "\p");
-
- /* Show a dialog so the user knows that we are searching for their file */
- search = GetNewDialog(kSearch, nil, (WindowPtr)-1);
-
- DrawDialog(search);
-
- /* Change the cursor to a watch */
- SetCursor(*(GetCursor(4)));
-
- /* Search. I am searching syncronously in this case */
- myError = PBCatSearch(csBlockPtr, false);
-
- /* returned, get rid of the dialog */
- DisposeDialog(search);
-
- /* change the cursor back to an arrow */
- InitCursor();
-
- /* See if there were any errors. Also, see if a file was found */
- /* ioActMatchCount will show how many files were really found if */
- /* we had asked for more than one */
- if (myError == noErr && csBlockPtr->ioActMatchCount != 0) {
- /* found a file with no errors. Put the filename in a ParamText */
- /* string show we can show the user */
-
- ParamText(&csBlockPtr->ioMatchPtr[0].name, "\p", "\p", "\p");
- /* show the user */
- alertResult = Alert(kFoundIt, nil);
- }
-
- /* no matter what happened, kill the memory we had allocated */
- if (csBlockPtr) {
- if (csBlockPtr->ioSearchInfo1)
- DisposePtr((Ptr)csBlockPtr->ioSearchInfo1);
- if (csBlockPtr->ioSearchInfo2)
- DisposePtr((Ptr)csBlockPtr->ioSearchInfo2);
- if (csBlockPtr->ioMatchPtr)
- DisposePtr((Ptr)csBlockPtr->ioMatchPtr);
- if (csBlockPtr->ioOptBuffer)
- DisposePtr((Ptr)csBlockPtr->ioOptBuffer);
- DisposePtr((Ptr)csBlockPtr);
- }
-
- /* catsearch section end */
-
- }
-
-
-
- /* The rest of this file is routines to support the creator/type dialog box, they */
- /* are not important to PBCatSearch. All of these routines were taken from my */
- /* DialogBits sample code, please see that code for more Dialog Manager techniques */
-
- /* Gets the ControlHandle for the item you want in the dialog box thebox. */
- /* Handy for setting checkboxes and radio buttons */
- ControlHandle SnatchHandle(DialogPtr thebox, short theGetItem)
- {
- short itemtype;
- Rect itemrect;
- Handle thandle;
-
- GetDialogItem(thebox, theGetItem, &itemtype, &thandle, &itemrect);
- return((ControlHandle)thandle);
- }
-
- /* This is our dialog filter, does not let the user type more than 4 characters */
- /* in the edit lines, since Creators and Types are four characters only */
- pascal Boolean letterFilter(DialogPtr dialer, EventRecord *myDialogEvent, short *theDialogItem)
- {
- Boolean returnVal = false;
- char myStr[10];
- char theKey;
- /* Find out how many characters are currently selected */
- short selStart = (*((DialogPeek)dialer)->textH)->selStart;
- short selEnd = (*((DialogPeek)dialer)->textH)->selEnd;
- /* Was this a Key event? */
- if ((myDialogEvent->what == keyDown) || (myDialogEvent->what == autoKey)) {
- /* yes,check for return key first */
- theKey = myDialogEvent->message & charCodeMask;
- if (theKey == kReturnKey || theKey == kEnterKey) {
- /* if they typed Return or Enter, exit the dialog */
- *theDialogItem = 1; /* say item 1 (OK button) hit */
- return(true);
- }
- /* Here I am getting the text of the currently active edit line */
- GetDialogItemText((Handle)SnatchHandle(dialer, ((DialogPeek)dialer)->editField + 1), myStr);
- /* Will this key make the line hold more than 4 characters? */
- if (myStr[0] > 3) {/* yes, see what the key is */
- /* if the jey is an edit key (like a right arrow), allow the */
- /* keystroke. Also allow the keystroke if there are any */
- /* characters selected, since they will be replaced by this new */
- /* keystroke */
- if (IsEditKey(theKey) || (selStart != selEnd)) {
- /* this is a safe key, let the Dialog Manager add it to the edit line */
- returnVal = false; /* don't filter out editing keys */
- } else {
- /* Not an edit key, and nothing selected. This would cause the */
- /* text in this edit line to be too long (over 4 characters) */
- /* so don't let it in */
- SysBeep(1); /* complain a little */
- returnVal = true; /* tell the dialog manager that we handled this already and */
- /* it doesn't have to, so the keystroke will _not_ get */
- /* added to the edit line */
-
- }
- }
- }
- return(returnVal);
- }
-
- /* IsEditKey is a handy routine to see if the current key is an edit key, like */
- /* an arrow key */
- Boolean IsEditKey(char theKey)
- {
- register qq;
- char editChars[] = {
- kLeftArrow, kUpArrow, kRightArrow, kDownArrow, kBackSpace, kTabKey
- };
- for (qq = 0; qq < sizeof(editChars); qq++) {
- if (theKey == editChars[qq])
- return(true);
- }
- return(false);
- }
-